<?php
/**
 * Laravel-Vue-Admin
 * @Author:技术铺
 * @Date:2021/11/22
 */

namespace App\Services;

use App\Http\Resources\RoleCollection;
use App\Models\Role;
use App\Models\RoleCategory;
use App\Models\RoleMenuPermission;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

/**
 * 角色模块服务层
 *
 * Class RoleService
 * @package App\Services
 */
class RoleService
{
    /**
     * 获取所有角色列表
     * [[id, name]...]
     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
     */
    public static function getAllList()
    {
        $collection = Role::where('status', 1)->get();
        $result = RoleCollection::make($collection)->only(['id', 'name'])->toArray(Request());
        return $result['items'];
    }

    /**
     * 获取所有角色ID列表
     * [[id]...]
     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
     */
    public static function getAllIds()
    {
        $collection = Role::where('status', 1)->get();
        return RoleCollection::make($collection)->only(['id'])->toArray(Request());
    }

    /**
     * 获取角色名称
     * @param int $id
     * @return string
     */
    public static function getName($id = 0)
    {
        if ($id == 0) return "";
        $getDetail = Role::find($id);
        return $getDetail ? $getDetail['name'] : '';
    }

    /**
     * 更新或创建角色信息，同时更新菜单权限表、栏目权限表信息
     *
     * @param $role // 创建场景时，设置为null
     * @param array $data
     * @return bool
     */
    public static function updateOrCreate($role = null, $data = [])
    {
        if (empty($data)) return false;
        $menu_permission_ids = $data['menu_permission_ids'];
        $category_ids = $data['category_ids'];
        unset($data['menu_permission_ids']);
        unset($data['category_ids']);
        $is_new = $role == null ? 1 : 0; // 是否新增
        $time = Carbon::now();
        if ($role == null) {
            $role = new Role($data);
            $role->save();
        } else if ($role instanceof Role) {
            $role->update($data);
        } else {
            return false;
        }

        /**
         * 菜单权限处理
         */

        $submitMPData = [];
        collect($menu_permission_ids)->each(function ($menu) use ($role, &$submitMPData, $time) {
            if (empty($menu['permission_ids'])) {
                array_push($submitMPData, ['role_id' => $role->id, 'menu_id' => $menu['menu_id'], 'permission_id' => 0]);
            } else {
                collect($menu['permission_ids'])->each(function ($permission_id) use ($role, $menu, &$submitMPData, $time) {
                    array_push($submitMPData, ['role_id' => $role->id, 'menu_id' => $menu['menu_id'], 'permission_id' => $permission_id]);
                });
            }
        });

        $insertingMPData = [];
        if ($is_new) {
            $insertingMPData = $submitMPData;
        } else {
            // 与当前库对比，不同的则写入；当前库与其对比不同则删除；两者一致则不处理
            if (empty($submitMPData)) {
                RoleMenuPermission::where('role_id', '=', $role->id)->delete();
            } else {
                $currentMPdata = RoleMenuPermission::where('role_id', $role->id)->select('role_id', 'menu_id', 'permission_id')->get()->toArray();
                if (!empty($currentMPdata)) {
                    foreach ($submitMPData as $sItem) {
                        if (!in_array($sItem, $currentMPdata)) $insertingMPData[] = $sItem;
                    }
                    $deletingPMWhere = [];
                    foreach ($currentMPdata as $cItem) {
                        if (!in_array($cItem, $submitMPData)) {
                            $deletingPMWhere[] = [['menu_id', $cItem['menu_id']], ['permission_id', $cItem['permission_id']]];
                        }
                    }
                    if (!empty($deletingPMWhere)) {
                        RoleMenuPermission::where(function ($query) use ($deletingPMWhere) {
                            foreach ($deletingPMWhere as $k => $v) {
                                $k == 0 ? $query->where($v) : $query->orWhere($v);
                            }
                        })->delete();
                    }
                } else {
                    $insertingMPData = $submitMPData;
                }
            }
        }

        // 写入菜单权限新数据
        if (!empty($insertingMPData)) {
            foreach ($insertingMPData as $key => $value) {
                $insertingMPData[$key] = array_merge($value, [
                    'created_user_id' => $role->created_user_id,
                    'created_at' => $time,
                    'updated_at' => $time
                ]);
            }
            DB::table('role_menu_permission')->insert($insertingMPData);
        }

        /**
         * 栏目权限处理
         */

        // 与当前库对比，一致则不更新，不同的则删除
        $current_category_ids = $role->roleCategory()->pluck('info_category_id');
        $deleting_diff_category_ids = collect($current_category_ids)->diff($category_ids)->all();
        $inserting_diff_category_ids = collect($category_ids)->diff($current_category_ids)->all();
        if (!empty($deleting_diff_category_ids)) {
            RoleCategory::where('role_id', '=', $role->id)->whereIn('info_category_id', $deleting_diff_category_ids)->delete();
        }

        // 与当前库对比，一致则不更新，不同的则写入
        if (!empty($inserting_diff_category_ids)) {
            $role_category_data = collect($inserting_diff_category_ids)->map(function ($info_category_id) use ($role, $time) {
                return [
                    'role_id' => $role->id,
                    'info_category_id' => $info_category_id,
                    'created_user_id' => $role->created_user_id,
                    'created_at' => $time,
                    'updated_at' => $time
                ];
            })->toArray();
            DB::table('role_category')->insert($role_category_data);
        }

        return true;
    }
}
